
package com.hlkj.pay.service.pay.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hlkj.framework.common.pojo.PageResult;
import com.hlkj.framework.common.util.collection.CollectionUtils;
import com.hlkj.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.hlkj.pay.common.constants.RedisConstants;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.dto.pay.PayWayQueryDto;
import com.hlkj.pay.infrastructure.mapper.pay.PayWayMapper;
import com.hlkj.pay.infrastructure.model.pay.PayWayDO;
import com.hlkj.pay.service.pay.IPayWayService;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author HlpayTeam
 * @date 2024/09/23 11:22
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class PayWayServiceImpl implements IPayWayService {

    private final PayWayMapper payWayMapper;

    @Override
    public PageResult<PayWayDO> queryPage(PayWayQueryDto payWayQueryDto) {
        return payWayMapper.selectPage(payWayQueryDto, buildWrapper(payWayQueryDto));
    }

    @Override
    public List<PayWayDO> queryList(PayWayQueryDto payWayQueryDto) {
        return payWayMapper.selectList(buildWrapper(payWayQueryDto));
    }

    @Override
    public PayWayDO detail(Long id) {
        return payWayMapper.selectById(id);
    }

    @Override
    @Cacheable(value = RedisConstants.PAY_WAY_INFO, key = "#code", unless = "#result == null")
    public PayWayDO queryByCode(String code) {
        PayWayQueryDto payWayQueryDto = new PayWayQueryDto();
        payWayQueryDto.setCode(code);
        List<PayWayDO> payWayList = queryList(payWayQueryDto);
        if (CollectionUtils.isEmpty(payWayList)) {
            return null;
        }
        return payWayList.get(0);
    }

    @Override
    public List<PayWayDO> queryByCodes(List<String> codes) {
        PayWayQueryDto payWayQueryDto = new PayWayQueryDto();
        payWayQueryDto.setCodes(codes);
        return queryList(payWayQueryDto);
    }

    @Override
    public PayWayDO queryByName(String name) {
        PayWayQueryDto payWayQueryDto = new PayWayQueryDto();
        payWayQueryDto.setName(name);
        List<PayWayDO> payWayList = queryList(payWayQueryDto);
        if (CollectionUtils.isEmpty(payWayList)) {
            return null;
        }
        return payWayList.get(0);
    }

    @Override
    public void save(PayWayDO payWayDO) {
        payWayMapper.insert(payWayDO);
    }

    @Override
    @CacheEvict(value = RedisConstants.PAY_WAY_INFO, key = "#payWayDO.code")
    public void update(PayWayDO payWayDO) {
        payWayMapper.updateById(payWayDO);
    }

    @Override
    @CacheEvict(value = RedisConstants.PAY_WAY_INFO, key = "#code")
    public void del(String code) {
        PayWayQueryDto payWayQueryDto = new PayWayQueryDto();
        payWayQueryDto.setCode(code);
        payWayMapper.delete(buildWrapper(payWayQueryDto));
    }

    @Override
    @CacheEvict(value = RedisConstants.PAY_WAY_INFO, key = "#code")
    public void updatePayWayStatus(String code, Integer status) {
        PayWayQueryDto payWayQueryDto = new PayWayQueryDto();
        payWayQueryDto.setCode(code);
        PayWayDO payWayDO = new PayWayDO();
        payWayDO.setStatus(status);
        payWayMapper.update(payWayDO, buildWrapper(payWayQueryDto));
    }

    @Override
    public PayWayDO queryByType(Integer payType, PayEnums.SCENE_PAY_TYPE scenePayType, Integer sceneType) {
        PayWayQueryDto payWayQueryDto = new PayWayQueryDto();
        payWayQueryDto.setType(payType);
        payWayQueryDto.setSubType(scenePayType.getType());
        payWayQueryDto.setSceneType(sceneType);
        List<PayWayDO> payWayDOS = payWayMapper.selectList(buildWrapper(payWayQueryDto));
        if (CollectionUtils.isEmpty(payWayDOS)) {
            PayWayDO payWayDO = queryByTypeBase(payType, scenePayType, null);
            if (payWayDO == null) {
                return queryByTypeBase(payType, null, null);
            }
            return payWayDO;
        }
        return payWayDOS.get(0);
    }
    public PayWayDO queryByTypeBase(Integer payType, PayEnums.SCENE_PAY_TYPE scenePayType, Integer sceneType) {
        PayWayQueryDto payWayQueryDto = new PayWayQueryDto();
        payWayQueryDto.setType(payType);
        if(scenePayType!=null){
            payWayQueryDto.setSubType(scenePayType.getType());
        }
        payWayQueryDto.setSceneType(sceneType);
        List<PayWayDO> payWayDOS = payWayMapper.selectList(buildWrapper(payWayQueryDto));
        if (CollectionUtils.isEmpty(payWayDOS)) {
            return null;
        }
        return payWayDOS.get(0);
    }

    /**
     * 查询条件封装
     *
     * @param payWayQueryDto
     * @return
     */
    LambdaQueryWrapper<PayWayDO> buildWrapper(PayWayQueryDto payWayQueryDto) {
        LambdaQueryWrapperX<PayWayDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eqIfPresent(PayWayDO::getCode, payWayQueryDto.getCode());
        queryWrapper.inIfPresent(PayWayDO::getCode, payWayQueryDto.getCodes());
        queryWrapper.likeIfPresent(PayWayDO::getCode, payWayQueryDto.getLikeCode());
        queryWrapper.eqIfPresent(PayWayDO::getName, payWayQueryDto.getName());
        queryWrapper.likeIfPresent(PayWayDO::getName, payWayQueryDto.getLikeName());
        queryWrapper.eqIfPresent(PayWayDO::getType, payWayQueryDto.getType());
        queryWrapper.inIfPresent(PayWayDO::getType, payWayQueryDto.getTypes());
        queryWrapper.eqIfPresent(PayWayDO::getSceneType, payWayQueryDto.getSceneType());
        queryWrapper.eqIfPresent(PayWayDO::getFeeType, payWayQueryDto.getFeeType());
        queryWrapper.eqIfPresent(PayWayDO::getStatus, payWayQueryDto.getStatus());
        queryWrapper.eqIfPresent(PayWayDO::getSubType, payWayQueryDto.getSubType());
        return queryWrapper;
    }
}
